#include <GUI/GUI.hpp>
#include <GUI/Views/BoardView.hpp>
#include <FL/Fl.H>
#include <memory>
#include <Task/Task.h>
#include <pthread.h>
#include <atomic>
#include <iostream>
#include <thread>
using namespace std::chrono_literals;


namespace GUI
{
    static std::unique_ptr<BoardView> board_view;
    static constexpr double TICK_INTERVAL = 0.1; // 100ms 更新一次
    static pthread_t watcher_thread = 0; // 监视任务线程
    static std::atomic quit_requested{false};
    static bool exit_scheduled = false;

    static void exit_cb(void*)
    {
        if (auto* w = Fl::first_window()) w->hide();
    }

    // 定时回调：刷新界面
    static void timeout_cb(void* /*data*/)
    {
        if (quit_requested.load(std::memory_order_relaxed))
        {
            if (!exit_scheduled)
            {
                std::cout << "任务结束，3秒后退出..." << std::endl;
                Fl::add_timeout(3.0, exit_cb);
                exit_scheduled = true;
            }
            return; // 不再重复刷新
        }
        if (board_view) board_view->update_states();
        Fl::repeat_timeout(TICK_INTERVAL, timeout_cb);
    }


    // 监视线程：等待 g_task_thread 结束后唤醒 GUI 线程关闭窗口
    static void* watcher_func(void*)
    {
        if (g_task_thread)
        {
            pthread_join(g_task_thread, nullptr);
            g_task_thread = 0;
            quit_requested.store(true, std::memory_order_relaxed);
            Fl::awake();
        }
        return nullptr;
    }

    int start()
    {
        // 创建主窗口
        board_view = std::make_unique<BoardView>(1200, 550, "SimuBoard");
        // 创建主窗口
        board_view = std::make_unique<BoardView>(1200, 550, "SimuBoard");
        board_view->show();

        if (board_view) board_view->update_states();
        Fl::add_timeout(TICK_INTERVAL, timeout_cb);

        // 启动 watcher 线程
        if (!watcher_thread)
        {
            pthread_create(&watcher_thread, nullptr, watcher_func, nullptr);
        }

        const int ret = Fl::run();

        // 回收 watcher 线程
        if (watcher_thread)
        {
            pthread_join(watcher_thread, nullptr);
            watcher_thread = 0;
        }
        return ret;
    }
}
